/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package br.ufrn.engcomp.pds.helloopc.modelo.negocio;

import br.ufrn.engcomp.pds.helloopc.modelo.dominio.Controlador;
import br.ufrn.engcomp.pds.helloopc.modelo.dominio.ParametroConfiguracao;
import br.ufrn.engcomp.pds.helloopc.modelo.dominio.ServidorOPC;
import br.ufrn.engcomp.pds.helloopc.modelo.dominio.TagOPC;
import br.ufrn.engcomp.pds.helloopc.modelo.dominio.VariavelControlador;
import br.ufrn.engcomp.pds.helloopc.modelo.negocio.excecao.NegocioException;
import br.ufrn.engcomp.pds.helloopc.modelo.negocio.opc.ConexaoOPC;
import br.ufrn.engcomp.pds.helloopc.modelo.negocio.servico.ControladorServico;
import br.ufrn.engcomp.pds.helloopc.modelo.negocio.servico.ParametroConfiguracaoServico;
import br.ufrn.engcomp.pds.helloopc.modelo.negocio.servico.ServidorOPCServico;
import br.ufrn.engcomp.pds.helloopc.modelo.negocio.servico.VariavelControladorServico;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import org.eclipse.persistence.tools.file.FileUtil;

/**
 *
 * @author Felipe Rivas
 */
public class CadastrarControladorNegocio {
    private ControladorServico controladorServico = new ControladorServico();
    private ServidorOPCServico servidorOPCServico = new ServidorOPCServico();
    private ParametroConfiguracaoServico parametroConfiguracaoServico = new ParametroConfiguracaoServico();
    private VariavelControladorServico variavelControladorServico = new VariavelControladorServico();
    private ListarVariaveisOPCNegocio listarVariaveisOPCNegocio = new ListarVariaveisOPCNegocio();

    public void inserir(Controlador controlador) throws NegocioException {
        try {
            controladorServico.beginTransaction();

            controladorServico.inserir(controlador);

            if (controlador.getArquivoAlgoritmo() != null) {
                FileInputStream arquivoAlgoritmoOrigem = new FileInputStream(new File(controlador.getArquivoAlgoritmo()));
                FileOutputStream arquivoAlgoritmoDestino = new FileOutputStream(new File("arquivos/" + controlador.getId() + ".class"));

                FileUtil.copy(arquivoAlgoritmoOrigem, arquivoAlgoritmoDestino);
            }

            controladorServico.commitTransaction();
        } catch (FileNotFoundException fnfex) {
            fnfex.printStackTrace();

            controladorServico.rollbackTransaction();

            throw new NegocioException("Arquivo do controlador não foi encontrado.");
        } catch (IOException ioex) {
            ioex.printStackTrace();

            controladorServico.rollbackTransaction();
                    
            throw new NegocioException("Erro ao baixar arquivo do controlador.");
        }
    }

    public void atualizar(Controlador controlador) throws NegocioException {
        try {
            controladorServico.beginTransaction();

            controladorServico.atualizar(controlador);

            if (controlador.getArquivoAlgoritmo() != null) {
                FileInputStream arquivoAlgoritmoOrigem = new FileInputStream(new File(controlador.getArquivoAlgoritmo()));
                FileOutputStream arquivoAlgoritmoDestino = new FileOutputStream(new File("arquivos/" + controlador.getId() + ".class"));

                FileUtil.copy(arquivoAlgoritmoOrigem, arquivoAlgoritmoDestino);
            }

            controladorServico.commitTransaction();
        } catch (FileNotFoundException fnfex) {
            fnfex.printStackTrace();

            controladorServico.rollbackTransaction();

            throw new NegocioException("Arquivo do controlador não foi encontrado.");
        } catch (IOException ioex) {
            ioex.printStackTrace();

            controladorServico.rollbackTransaction();

            throw new NegocioException("Erro ao baixar arquivo do controlador.");
        }
    }

    public void remover(Object id) {
        Controlador controlador = controladorServico.buscarPorID(id);

        controladorServico.remover(controlador);
    }

    public Controlador buscarControlador(Object id) {
        return controladorServico.buscarPorID(id);
    }

    public List<Controlador> listarControladores() {
        return controladorServico.buscarTodos();
    }

    public List<TagOPC> listarTagsOPC() throws NegocioException {
        return listarVariaveisOPCNegocio.listar();
    }

    public List<ParametroConfiguracao> sincronizarParametros(Controlador entidade) {
        parametroConfiguracaoServico.refresh(entidade.getParametrosConfiguracao());

        return entidade.getParametrosConfiguracao();
    }

    public List<VariavelControlador> sincronizarVariaveis(Controlador entidade) {
        variavelControladorServico.refresh(entidade.getVariaveisControlador());

        return entidade.getVariaveisControlador();
    }

    public ServidorOPC getServidorConectado() throws NegocioException {
        if (ConexaoOPC.isConnected()) {
            ServidorOPC servidorOPCConectado = servidorOPCServico.buscarPorID(ConexaoOPC.getCurrentInstance().getId());

            return servidorOPCConectado;
        }

        throw new NegocioException("Não está conectado a um servidor OPC.");
    }

    public ServidorOPC sincronizarServidorOPC(ServidorOPC servidorOPC) {
        servidorOPCServico.refresh(servidorOPC);

        return servidorOPC;
    }
}
